//
// Copyright (c) 2009-2011, chunquedong
//
// This file is part of ChunMap project
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
//
// History:
//   2011-10-29  Jed Young  Creation
//

using gfx
using fwt
using chunmapModel
using chunmapData
using chunmapUtil
using chunmapView
using slanData

**
** Select the feature
**
@Js
class SelectTool : Tool
{
  private Int x := 0
  private Int y := 0
  private Bool click := false
  Float d := 5f
  |Feature[]|? onSelectChange

  private Void mouseClicked(Event e) {
    Float minx := x - d
    Float miny := y - d
    Float maxx := x + d
    Float maxy := y + d
    env := Envelope(minx, miny, maxx, maxy)
    env2 := env.transform(map.view.screen2World)
    select(env2.envelope)
  }

  private Void select(Envelope env)
  {
    features := Feature[,]
    map.layers.each |lyr|
    {
      if (lyr is VectorLayer)
      {
        VectorLayer vl := lyr
        vl.dataSource.each(Condition.empty) |f|
        {
          shp := f as Shape
          if (shp != null)
          {
            if (env.intersectsGeometry(shp.geometry))
              features.add(f)
          }
        }
      }
    }

    finish(features)
    onSelectChange?.call(features)
    map.renderMap
  }

  Void finish(Feature[] features)
  {
    if (features.size == 0)
    {
      map.layers.selectedLayer = null
      return
    }

    fc := FeatureList
    {
      metadata = Metadata
      {
        name = "Features"
        type = GeometryType.geometryCollection
        crs = CoordRef.defVal
      }
      it.schema = Schema("Features", [,])
      envelope = features.first.envelope
    }

    features.each |f|
    {
      fc.add(f)
    }

    layer := VectorLayer.makeFeatureSet(fc)
    sym := GeneralSym
    {
      pointSym = SimplePointSym { brush = Color.makeRgb(255, 0, 255); size = 13 }
      lineSym = SimpleLineSym { pen = Pen { width = 4 } }
      polygonSym = SimplePolygonSym { pen = Pen { width = 4 }; fill = false }
    }
    layer.renderer = Renderer.makeDef([sym, ArrowSym()])
    map.layers.selectedLayer = layer
  }

  override Void actionEvent(Event e)
  {
    switch (e.id)
    {
      case EventId.mouseDown:
        x = e.pos.x
        y = e.pos.y
        click = true
      case EventId.mouseUp:
        if (click && x == e.pos.x && y == e.pos.y)
        {
          mouseClicked(e)
        }
      case EventId.mouseMove:
        if (x != e.pos.x || y != e.pos.y)
        {
          click = false
        }
      default: return
    }
  }
}